763. 划分字母区间

763. 划分字母区间

Similar Question

Solution Tips

方案一: 区间思路 (贪心)


var partitionLabels = function(s) {
    // 感觉是哈希表呀
    // 先根据字母统计出区间, 然后按照区间进行划分
    // 将重叠的区间合并为一个
    // 记录是否出现过, 以及对应的 index
    const map = {};
    // 根据出现的 order, push 区间
    const order = [];
    for (let i = 0; i < s.length; i++) {
        // 不能按照字母表排序, 要按照出现的顺序排序
        // 字符串好像就是插入顺序来的?
        // 不是, 字符串属性也是字典序的, 那就一边插入一遍排序
        const charCode = s[i];
        if (map[charCode] === undefined) {
            order.push([i]);
            map[charCode] = order.length - 1;
        }
        else {
            const o = map[charCode];
            order[o].push(i);
        }
    }
    // 记录 maxRight, 将所有 right 小于 maxRight 的都归为一组
    let start = 0;
    let maxRight = 0;
    let partLen = 0;
    const res = [];
    for (const list of order) {
        const l = list[0];
        const r = list[list.length - 1];

        if (maxRight >= l) {
            // 两个字母的区间有重叠, 只能合并到一起 part
            // 更新maxRight
            maxRight = Math.max(maxRight, r);
            partLen = maxRight - start + 1;
        }
        else {
            // 一个新的区间
            res.push(partLen);
            start = l;
            maxRight = r;
            partLen = maxRight - start + 1;
        }
    }
    // 最后一个区间
    partLen > 0 && res.push(partLen);

    return res;

};
console.log(partitionLabels(""))

方案二: 跳跃思路 (贪心)

只关心右边就够了, 到达了 maxRight 自然就是新区间, 所以不需要 start 和 l 变量

相当于是跳跃思路, 每次跳跃到能跳到最远的地方

var partitionLabels = function(s) {
    const last = new Array(26);
    const length = s.length;
    const codePointA = 'a'.codePointAt(0);
    for (let i = 0; i < length; i++) {
        last[s.codePointAt(i) - codePointA] = i;
    }
    const partition = [];
    let start = 0, end = 0;
    for (let i = 0; i < length; i++) {
        end = Math.max(end, last[s.codePointAt(i) - codePointA]);
        if (i == end) {
            partition.push(end - start + 1);
            start = end + 1;
        }
    }
    return partition;
};